#include <riscv/csr.h>
#include <riscv/asm-offset.h>
#include <riscv/asm.h>
#include <asm/linkage.h>

ENTRY(secondary_start_sbi)
	/* Mask all interrupts */
	csrw CSR_IE, zero
	csrw CSR_IP, zero

	/* Load the global pointer */
	load_global_pointer

	/*
	 * Disable FPU & VECTOR to detect illegal usage of
	 * floating point or vector in kernel space
	 */
	li t0, SR_FS_VS
	csrc CSR_STATUS, t0

	/* Set trap vector to spin forever to help debug */
	la a3, .Lsecondary_park
	csrw CSR_TVEC, a3

	/* a0 contains the hartid & a1 contains boot data */
	li a2, SBI_HART_BOOT_TASK_PTR_OFFSET
	add a2, a2, a1
	REG_L tp, (a2)
	li a3, SBI_HART_BOOT_STACK_PTR_OFFSET
	add a3, a3, a1
	REG_L sp, (a3)

.Lsecondary_start_common:
    call setup_trap_vector
    call smp_callin

.align 2
.Lsecondary_park:
	/*
	 * Park this hart if we:
	 *  - have too many harts on CONFIG_RISCV_BOOT_SPINWAIT
	 *  - receive an early trap, before setup_trap_vector finished
	 *  - fail in smp_callin(), as a successful one wouldn't return
	 */
	wfi
	j .Lsecondary_park
